import pandas as pd
import matplotlib.pyplot as plt
import warnings
import numpy as np
warnings.simplefilter(action='ignore', category=FutureWarning)
import plotly.express as px
import plotly.graph_objects as go
import plotly.io as pio
pio.renderers.default='notebook'
def normalize(df, how="min-max"):
if how == "min-max" :
return (df - df.min())/(df.max()-df.min())
if how == "mean" :
return (df-df.mean())/df.std()
def get_cp_indices_df(df_cp, df_indices, selected_coutry = None, data_resolution = "M", normalization="mean", normalize_cp=True) :
if not selected_coutry : selected_coutry = df_cp.country.unique()
df_cp_filter = df_cp[df_cp.country.isin(selected_coutry) ]
df_cp_filter = df_cp_filter.groupby([df_cp_filter.index.to_period(data_resolution)]).mean().reset_index()
df_cp_filter = df_cp_filter.set_index(df_cp_filter.timestamp).drop(["timestamp"], axis=1)
df_indices_filter = df_indices.groupby([df_indices.index.to_period(data_resolution)]).mean().reset_index()
df_indices_filter = df_indices_filter.set_index(df_indices_filter.timestamp).drop(["timestamp"], axis=1)
df_indices_filter = normalize(df_indices_filter, how=normalization)
if normalize_cp : df_cp_filter.capacity_factor = normalize(df_cp_filter.capacity_factor, how=normalization)
df_cp_indices = df_cp_filter.join(df_indices_filter)
return df_cp_indices[df_cp_indices.index.year>=1982]
def compare_cp_index(df_cp_indices, smoothing = False, smoothing_duration=6, indices = None, start=1990, end=2019, show_plot = True):
if indices :
df_cp_indices = df_cp_indices[indices+["capacity_factor"]]
df_cp_indices = df_cp_indices[(df_cp_indices.index.year > start) & (df_cp_indices.index.year < end)]
if smoothing : df_cp_indices = df_cp_indices.rolling(smoothing_duration, center=True).mean()
if show_plot :
fig = px.line(df_cp_indices.set_index(df_cp_indices.index.astype("str")),
title= ("normalized capacity factor and climate indices, smoothing={}".format(smoothing_duration) if smoothing else "normalized capacity factor and climate indices"))
fig.update_traces(visible='legendonly')
fig.update_traces(visible=True, selector=dict(name="capacity_factor"))
fig.show()
return df_cp_indices.corr().capacity_factor[:-1]
df_cp = pd.read_csv("dataset_with_timestamp")
df_cp = df_cp.drop(['hour', 'month', 'year', 'day'], axis=1)
df_cp['timestamp'] = pd.to_datetime(df_cp['timestamp'], format='%Y-%m-%d %H:%M:%S')
df_cp = df_cp.groupby(["timestamp","country"]).mean().reset_index()
df_cp = df_cp.set_axis(df_cp.timestamp)
df_cp = df_cp.drop(["timestamp"], axis=1)
indices = ["nao", "ao","mjo80e","mjo40w","mjo20e","mjo160e","mjo10w","nino34"]
df_indices = pd.read_csv("daily_indices_82_to_19.csv")
df_indices['timestamp'] = pd.to_datetime(df_indices['timestamp'], format='%Y-%m-%d')
df_indices = df_indices[["timestamp"]+indices]
df_indices = df_indices.set_axis(df_indices.timestamp)
df_indices = df_indices.drop(["timestamp"], axis=1)
Please click on the different index names to display them on the chart.
selected_coutry=["GB"]
data_resolution="M"
smoothing = False
df_cp_indices = get_cp_indices_df(df_cp, df_indices, selected_coutry=selected_coutry,data_resolution=data_resolution)
corr = compare_cp_index(df_cp_indices, indices=indices, start = 1990, show_plot= True, smoothing=smoothing)
Please click on the different index names to display them on the chart.
smoothing = True
smoothing_duration = 6
normalization = "mean"
df_cp_indices = get_cp_indices_df(df_cp, df_indices, selected_coutry=selected_coutry,data_resolution=data_resolution, normalization=normalization)
corr = compare_cp_index(df_cp_indices, indices=indices, start = 1990, show_plot= True, smoothing=smoothing, smoothing_duration= smoothing_duration )
corr
nao 0.478359 ao 0.283468 mjo80e 0.036305 mjo40w -0.003642 mjo20e 0.049313 mjo160e -0.055214 mjo10w 0.026495 nino34 -0.047231 Name: capacity_factor, dtype: float64
smoothing = True
smoothing_duration = 6
corr = dict()
for selected_country in df_cp.country.unique() :
df_cp_indices = get_cp_indices_df(df_cp, df_indices, selected_coutry=[selected_country])
corr[selected_country] = compare_cp_index(df_cp_indices, indices = indices, start = 1990, show_plot= False, smoothing=smoothing, smoothing_duration=smoothing_duration).to_list()
corr_df = pd.DataFrame.from_dict(corr, orient='index', columns = indices)
corr_df.index.name="country"
corr_df.style.background_gradient(vmin=-1, vmax=1,cmap='coolwarm')
| nao | ao | mjo80e | mjo40w | mjo20e | mjo160e | mjo10w | nino34 | |
|---|---|---|---|---|---|---|---|---|
| country | ||||||||
| AT | 0.401209 | 0.200381 | -0.026115 | 0.035699 | -0.007536 | 0.022667 | 0.014305 | -0.100477 |
| BE | 0.357454 | 0.130717 | 0.010730 | 0.022674 | 0.061220 | -0.054831 | 0.048417 | -0.018979 |
| BG | 0.317720 | -0.017226 | 0.054056 | -0.060836 | -0.068574 | 0.045268 | -0.077557 | 0.010304 |
| CH | 0.358206 | 0.084513 | -0.050144 | 0.077441 | 0.058760 | -0.029234 | 0.078436 | -0.095679 |
| CZ | 0.428832 | 0.269858 | -0.052162 | 0.056053 | -0.011895 | 0.040940 | 0.023017 | -0.034475 |
| DE | 0.425499 | 0.265625 | 0.012558 | 0.009589 | 0.024398 | -0.019538 | 0.018484 | -0.005466 |
| DK | 0.392979 | 0.283005 | 0.118568 | -0.076295 | 0.054574 | -0.093055 | -0.011928 | 0.020224 |
| ES | 0.144505 | -0.268615 | 0.057807 | -0.016691 | 0.079031 | -0.094081 | 0.037202 | 0.008658 |
| FI | 0.455093 | 0.356469 | 0.073305 | -0.045912 | 0.019648 | -0.041326 | -0.015784 | -0.035780 |
| FR | 0.326560 | 0.029027 | 0.035180 | -0.006669 | 0.040623 | -0.045499 | 0.019122 | 0.014844 |
| GB | 0.478359 | 0.283468 | 0.036305 | -0.003642 | 0.049313 | -0.055214 | 0.026495 | -0.047231 |
| GR | 0.147129 | 0.058421 | 0.064330 | -0.023816 | 0.092306 | -0.118249 | 0.042828 | -0.078176 |
| HR | 0.252079 | -0.086281 | 0.026818 | 0.010103 | 0.085786 | -0.093855 | 0.057704 | -0.110292 |
| HU | 0.309229 | 0.106228 | -0.012991 | 0.034501 | 0.021568 | -0.011096 | 0.031221 | -0.105912 |
| IE | 0.497552 | 0.276609 | 0.060182 | -0.034120 | 0.019501 | -0.037373 | -0.009001 | -0.015616 |
| IT | 0.244602 | -0.174834 | 0.050184 | -0.006289 | 0.090978 | -0.107204 | 0.051177 | -0.122685 |
| LT | 0.379813 | 0.309447 | 0.064033 | -0.016623 | 0.085946 | -0.099994 | 0.041384 | -0.042970 |
| LU | 0.338433 | 0.094717 | -0.022730 | 0.038847 | 0.020475 | -0.001734 | 0.032751 | 0.002173 |
| LV | 0.371548 | 0.330979 | 0.060166 | -0.013994 | 0.089015 | -0.102719 | 0.045047 | -0.065982 |
| ME | 0.281457 | -0.023618 | 0.042861 | -0.029706 | -0.001819 | -0.016779 | -0.018807 | -0.070122 |
| NL | 0.385079 | 0.175133 | -0.001534 | 0.030204 | 0.050473 | -0.039872 | 0.046217 | -0.039781 |
| NO | 0.489668 | 0.360442 | 0.075869 | -0.056171 | 0.003300 | -0.027937 | -0.031296 | -0.028138 |
| PL | 0.409841 | 0.330563 | 0.033006 | -0.016295 | 0.003546 | -0.009073 | -0.008737 | -0.001456 |
| PT | 0.083955 | -0.313192 | 0.062567 | -0.024090 | 0.058706 | -0.075291 | 0.020393 | 0.051376 |
| RO | 0.334665 | -0.000529 | 0.057750 | -0.046633 | -0.021992 | 0.001007 | -0.041362 | -0.027337 |
| SE | 0.466131 | 0.394496 | 0.122938 | -0.080879 | 0.050841 | -0.091888 | -0.016507 | -0.035804 |
| SI | 0.134383 | -0.102864 | 0.021968 | 0.013913 | 0.105362 | -0.110448 | 0.072288 | -0.080003 |
| SK | 0.404836 | 0.153272 | -0.024170 | 0.053398 | 0.054446 | -0.036460 | 0.062221 | -0.106471 |
Use the slider to switch between indices.
melted = corr_df.melt(ignore_index=False, var_name='clim_index')
fig=px.choropleth_mapbox(melted,
geojson="https://raw.githubusercontent.com/leakyMirror/map-of-europe/master/GeoJSON/europe.geojson",
featureidkey='properties.ISO2',
locations=melted.index, #column in dataframe
animation_frame =melted.clim_index, #dataframe
color=melted.value, #dataframe
zoom=1, center = {"lat": 56.4, "lon": 15.0},
mapbox_style="carto-positron",
color_continuous_scale="Viridis",
opacity = 0.5,
title='Correlation between smoothened monthly capacity factor and different climate indices' ,
)
fig.show()
Observations :
Concerning nao and ao :
Other indices :
data_resolution = "d"
selected_country = ["GB"]
normalize_cp=False
Please click on the different index names to display them on the chart.
df_cp_indices = get_cp_indices_df(df_cp, df_indices, selected_coutry=selected_country, data_resolution=data_resolution, normalization="min-max",normalize_cp=False )
df_low_wind = df_cp_indices.copy()
df_low_wind["low_bool"] = (df_low_wind.capacity_factor<0.1)
fig = go.Figure()
fig.add_scattergl(x=df_low_wind.index.astype("str"), y=df_low_wind.capacity_factor, line={'color': 'lightgrey',"width":1},name = "capacity factor",legendgroup="cp")
fig.add_scattergl(x=df_low_wind.index.astype("str"), y=df_low_wind.capacity_factor.where(df_low_wind.low_bool), marker=dict(color='grey',size=20), showlegend=False,legendgroup="cp")
for index in indices :
fig.add_scattergl(x=df_low_wind.index.astype("str"), y=df_low_wind[index], line={'color': 'blue',"width":1},visible="legendonly", legendgroup=index, name=index)
fig.add_scattergl(x=df_low_wind.index.astype("str"), y=df_low_wind[index].where(df_low_wind.low_bool), line={'color': 'red',"width":2},visible="legendonly", legendgroup=index, showlegend=False)
fig.update_layout(title="Normalized climate indices. Periods corresponding to low wind power events are highlighted in red")
fig.show()